import java.util.ArrayList;
import java.util.Scanner;
/**
 * Created by L.jp
 * Description:
 * 定义一个二维数组 N*M ，如 5 × 5 数组下所示：
 * int maze[5][5] = {
 * 0, 1, 0, 0, 0,
 * 0, 1, 1, 1, 0,
 * 0, 0, 0, 0, 0,
 * 0, 1, 1, 1, 0,
 * 0, 0, 0, 1, 0,
 * };
 * 它表示一个迷宫，其中的1表示墙壁，0表示可以走的路，只能横着走或竖着走，不能斜着走，要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
 * 数据范围： 2 \le n,m \le 10 \2≤n,m≤10  ， 输入的内容只包含 0 \le val \le 1 \0≤val≤1
 *
 * 输入描述：
 * 输入两个整数，分别表示二维数组的行数，列数。再输入相应的数组，其中的1表示墙壁，0表示可以走的路。数据保证有唯一解,不考虑有多解的情况，即迷宫只有一条通道。
 *
 * 输出描述：
 * 左上角到右下角的最短路径，格式如样例所示。
 *
 * 示例1
 * 输入：
 * 5 5
 * 0 1 0 0 0
 * 0 1 1 1 0
 * 0 0 0 0 0
 * 0 1 1 1 0
 * 0 0 0 1 0

 * 输出：
 * (0,0)
 * (1,0)
 * (2,0)
 * (2,1)
 * (2,2)
 * (2,3)
 * (2,4)
 * (3,4)
 * (4,4)
 * User: 86189
 * Date: 2022-03-20
 * Time: 14:41
 */
class Pos{
    int x;
    int y;
    public Pos(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public class Main {
    //由于输出是一个坐标的固定形式，注意不是一个二维数组的形式，是一个坐标的形式，所以我们需要另外定义一个坐标类，来存储和输出坐标
    public static  void searchPath(int[][] arr,int x,int y,int row,int col,int[][] visited,
                                   ArrayList<Pos> path,ArrayList<Pos> minPath){
        //首先看这个点是否越界，被访问过，是否是障碍，是的话直接返回
        if(x<0 || x >=row || y<0 || y>=col || visited[x][y]==1 || arr[x][y]==1){
            return;
        }
        //如果不是这些情况，就加入路劲集合
        //每一个点都是一个新的点类
        path.add(new Pos(x,y));
        //标记被访问过
        visited[x][y] = 1;
        //再看当前位置是否是出口，是的话说明找到一条新的路径，需要加入最短路径的集合，更新最短路径
        if(x==row-1 && y==col-1){
            //path.add(new Pos(x, y)) ,前面已经做过加入路径集合的处理了，不需要再加入路径集合了
            //直接判断需不需要更新最短路径
            if(minPath.isEmpty() || path.size() < minPath.size()){
                //当最短路径是空时，或者路径和的大小小于最短路径和的大小就需要把路径和的每个点加入到最短路径中，更新最短路径
                minPath.clear();  //需要情况之前的最短路径和
                for(Pos pos:path){
                    minPath.add(pos);
                }
            }
        }
        //做完判断之后，就去搜索周围的四个点，还是一样的判断，采用递归
        searchPath(arr, x-1, y, row, col, visited, path, minPath);
        searchPath(arr, x+1, y, row, col, visited, path, minPath);
        searchPath(arr, x, y-1, row, col, visited, path, minPath);
        searchPath(arr, x, y+1, row, col, visited, path, minPath);
        //当返回时说明遇到了越界，有障碍，被访问过的任意一种情况，那么就需要回溯回去
        //说明这个点不符合情况，删除这个点，并且还原回去没有被访问过
        //回溯
        path.remove(path.size() - 1);
        visited[x][y]=0;
    }
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int row=scanner.nextInt();
        int col=scanner.nextInt();
        int[][] arr=new int[row][col];
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                arr[i][j]=scanner.nextInt();
            }
        }
        //作为临时存储的路径
        ArrayList<Pos> path=new ArrayList<>();
        //存储最短路径
        ArrayList<Pos> minPath=new ArrayList<>();
        //存储访问过的点
        int[][] visited=new int[row][col];
        //搜索最短路径,dfs+回溯
        searchPath(arr,0,0,row,col,visited,path,minPath);
        //输出最短路径
        for(Pos pos:minPath) {
            System.out.println("(" + pos.x + "," + pos.y + ")");
        }
    }
}
